package cn.hinglo.common.plugin.mqtt;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author hinglo
 */
@Slf4j
public class MqttKit {
    private static final String BASE_URL = "http://127.0.0.1:8081/";
    private static final String USERNAME = "admin";
    private static final String PASSWORD = "public";

    /*============= username 认证相关接口 ===============*/

    /***
     * 添加认证mqtt的用户名与密码
     * @param username 用户名
     * @param password 密码
     */
    public static void addAuthUsername(String username, String password) {
        Map<String, Object> body = new HashMap<>(2);
        body.put("username", username);
        body.put("password", password);
        postForRequest("api/v4/auth_username", body);
    }

    /***
     * 获取所有的认证的用户名
     * @return 返回认证用户名
     */
    public static List<String> getAllAuthUsername() {
        String response = getForRequest("api/v4/auth_username");
        JSONArray objects = JSONUtil.parseArray(response);
        return JSONUtil.toList(objects, String.class);
    }

    /***
     * 获取所有的认证的用户名
     * @return 返回认证用户名
     */
    public static void deleteAuthUsername(String username) {
        deleteForRequest(String.format("api/v4/auth_username/%s", username));
    }

    /***
     * 修改认证mqtt的用户名的密码
     * @param username 用户名
     * @param password 密码
     */
    public static void changeAuthUsernamePassword(String username, String password) {
        Map<String, Object> body = new HashMap<>(2);
        body.put("password", password);
        putForRequest(String.format("api/v4/auth_username/%s", username), body);
    }

    /***
     * 返回制定用户名的信息
     * @param username 用户名
     * @return 返回基本信息Map
     */
    public static Map<String, Object> getAuthUsername(String username) {
        String response = getForRequest(String.format("api/v4/auth_username/%s", username));
        if (StrUtil.isNotBlank(response)) {
            return JSONUtil.parseObj(response);
        }
        return new HashMap<>(1);
    }

    /*============= clientId 认证相关接口 ===============*/

    /***
     * 添加认证mqtt的clientId与密码
     * @param clientId 客户端连接ID
     * @param password 密码
     */
    public static void addAuthClientId(String clientId, String password) {
        Map<String, Object> body = new HashMap<>(2);
        body.put("clientId", clientId);
        body.put("password", password);
        postForRequest("api/v4/auth_clientid", body);
    }


    /***
     * 获取所有的认证的clientId
     * @return 返回认证用户名
     */
    public static List<String> getAllAuthClientId() {
        String response = getForRequest("api/v4/auth_clientid");
        JSONArray objects = JSONUtil.parseArray(response);
        return JSONUtil.toList(objects, String.class);
    }

    /***
     * 修改认证mqtt的clientId的密码
     * @param clientId 用户名
     * @param password 密码
     */
    public static void changeAuthClientIdPassword(String clientId, String password) {
        Map<String, Object> body = new HashMap<>(2);
        body.put("password", password);
        putForRequest(String.format("api/v4/auth_clientid/%s", clientId), body);
    }

    /***
     * 返回制定用clientId的信息
     * @param clientId 用户名
     * @return 返回基本信息Map
     */
    public static Map<String, Object> getAuthClientInfo(String clientId) {
        String response = getForRequest(String.format("api/v4/auth_clientid/%s", clientId));
        if (StrUtil.isNotBlank(response)) {
            return JSONUtil.parseObj(response);
        }
        return new HashMap<>(1);
    }

    /***
     * 删除指定的客户端ID
     * @param clientId 用户名
     * @return 返回基本信息Map
     */
    public static void deleteAuthClientId(String clientId) {
        deleteForRequest(String.format("api/v4/auth_clientid/%s", clientId));
    }




    /*============= 请求工具 ===============*/

    /***
     * get 请求方式
     * @param url 请求地址
     * @return 返回结果
     */
    public static String getForRequest(String url) {
        return request(Method.GET, url, null);
    }

    /***
     *  Post 请求方式
     * @param url 请求地址
     * @param body 请求内容
     * @return 返回结果
     */
    public static String postForRequest(String url, Map<String, Object> body) {
        return request(Method.POST, url, body);
    }

    /***
     *  Post 请求方式
     * @param url 请求地址
     * @param body 请求内容
     * @return 返回结果
     */
    public static String putForRequest(String url, Map<String, Object> body) {
        return request(Method.PUT, url, body);
    }

    /***
     *  delete 请求方式
     * @param url 请求地址
     * @return 返回结果
     */
    public static String deleteForRequest(String url) {
        return request(Method.DELETE, url, null);
    }


    /***
     * 无参数请求方法
     * @param method 请求方式
     * @param url url
     * @return 返回结果
     */
    public static String request(Method method, String url) {
        return request(method, url, null);
    }

    /***
     *
     * @param method 请求方法
     * @param url 请求地址
     * @param param 参数内容
     * @return 返回响应结果
     */
    public static String request(Method method, String url, Map<String, Object> param) {
        HttpRequest request = HttpUtil.createRequest(method, BASE_URL + url);
        request.header("Authorization", "Basic " + Base64.encode(USERNAME + ":" + PASSWORD));
        if (method == Method.POST || method == Method.PUT) {
            if (param != null) {
                request.body(JSONUtil.toJsonStr(param), "application/json");
            }
        }
        if (param != null) {
            request.form(param);
        }
        String body = request.execute().body();
        log.info("请求地址：{} 请求方式：{},请求参数：{} 请求结果：{}", BASE_URL + url, method, param, body);
        JSON parse = JSONUtil.parse(body);
        Object code = JSONUtil.getByPath(parse, "code");
        // 如果code 不等200 就表示请求失败了
        if (code != null && Integer.parseInt(code.toString()) == 0) {
            Object data = JSONUtil.getByPath(parse, "data");
            if (data != null) {
                return data.toString();
            } else {
                return null;
            }
        }
        throw new RuntimeException("请求发生异常,请查看具体日志信息");
    }


}
